#include <iostream>
#include <semaphore.h>
#include <vector>
#define NUM 5
template<class T>
class RingQuene
{
  private:
    std::vector<T> q;
    int cap;
    sem_t blank_sem;
    sem_t data_sem;
    int c_pos=0;
    int p_pos=0;


    void P(sem_t& sem)
    {
      sem_wait(&sem);
    }

    void V(sem_t& sem)
    {
      sem_post(&sem);
    }

  public:
    RingQuene()
    {
      q.reserve(5);
      cap=NUM;
      sem_init(&blank_sem,0,5);
      sem_init(&data_sem,0,0);      
    }

    ~RingQuene()
    {
      sem_destroy(&blank_sem);
      sem_destroy(&data_sem);
    }

    void push(const T& in)
    {
      P(blank_sem);
      q[p_pos]=in;
      V(data_sem);
      //p_pos不属于公共资源，所以可以在外面++
      p_pos++;
      p_pos=p_pos%cap;
    }

    void pop(T& out)
    {
      P(data_sem);
      out=q[c_pos];
      V(blank_sem);
      c_pos++;
      c_pos=c_pos%cap;
    }
};
